#include "common/core/mi_rtti.h"
#include <map>
#include <queue>
ENGINE_BEGIN
static std::map<std::string, Class *> * name_class;
static std::vector<std::pair<std::string, std::string> > * name_father;
void initializeRTTI () {
    for(auto e : *name_father) {
        Class * A = name_class->operator[](e.first);
        Class * B = name_class->operator[](e.second);
        A->m_fathers.push_back(B);
    }
}

const Class *findClass(const std::string &s) {
    return name_class->operator[](s);
}

bool Class::isChildOf (const Class *c) const {
    std::queue<const Class *> que;
    std::map<const Class *, bool> vis;
    for(auto f : m_fathers) {
        que.push(f);
        vis[f] = true;
        if(f == c) return true;
    }
    while(!que.empty()) {
        const Class * u = que.front();
        que.pop();
        for(auto e : u->m_fathers) {
            if(vis[e]) continue;
            if(!e) continue ;
            vis[e] = true;
            que.push(e);
            if(e == c) return true;
        }
    }
    return false;
}

std::vector<const Class *> Class::getSubclasses() const {
    std::vector<const Class * > ret;
    for(auto e : *name_father)
        if(e.second == m_name)
            ret.push_back(name_class->operator[](e.first));
    return ret;
}

Class::Class(const std::string & name, const std::string & desc, std::vector<std::string> fathers) {
    m_name = name;
    m_description = desc;
    if(name_class == nullptr) name_class = new std::map<std::string, Class*> ;
    if(name_father == nullptr) name_father = new std::vector<std::pair<std::string, std::string> > ;
    name_class->operator[](name) = this;
    for(auto father: fathers)
        name_father->push_back({name, father});
}

const Class *Class::getOneFather() const {
    if(m_fathers.size()) return m_fathers[0];
    else return nullptr;
}

// Sun·万物起源·阳光普照之主·IsMe

IMPLEMENT_CLASS(Object, u8"所有类的基类", SunIsMe);

std::string Object::toString () const {
    return getClass()->getName();
}
